package com.bocloud.cmp.driver.utils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.springframework.util.StringUtils;

import com.bocloud.cmp.model.ClusterModel;
import com.bocloud.cmp.model.DataStoreModel;
import com.bocloud.cmp.model.HostModel;
import com.bocloud.cmp.model.NetworkCardModel;
import com.bocloud.cmp.model.NetworkModel;
import com.bocloud.cmp.model.PortGroupModel;
import com.bocloud.cmp.model.ServerModel;
import com.bocloud.cmp.model.SnapshotModel;
import com.bocloud.cmp.model.VDCModel;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.vmware.vim25.DatastoreSummary;
import com.vmware.vim25.DistributedVirtualSwitchHostMemberPnicBacking;
import com.vmware.vim25.DistributedVirtualSwitchHostMemberPnicSpec;
import com.vmware.vim25.HostListSummary;
import com.vmware.vim25.HostPortGroupConfig;
import com.vmware.vim25.HostProxySwitch;
import com.vmware.vim25.HostSystemConnectionState;
import com.vmware.vim25.HostSystemPowerState;
import com.vmware.vim25.HostVirtualNic;
import com.vmware.vim25.HostVirtualSwitchBondBridge;
import com.vmware.vim25.HostVirtualSwitchConfig;
import com.vmware.vim25.InvalidProperty;
import com.vmware.vim25.ManagedObjectReference;
import com.vmware.vim25.PhysicalNic;
import com.vmware.vim25.RuntimeFault;
import com.vmware.vim25.VirtualDevice;
import com.vmware.vim25.VirtualDeviceDeviceBackingInfo;
import com.vmware.vim25.VirtualDisk;
import com.vmware.vim25.VirtualEthernetCard;
import com.vmware.vim25.VirtualEthernetCardDistributedVirtualPortBackingInfo;
import com.vmware.vim25.VirtualMachineConfigInfo;
import com.vmware.vim25.VirtualMachineSnapshotTree;
import com.vmware.vim25.VirtualMachineSummary;
import com.vmware.vim25.mo.ClusterComputeResource;
import com.vmware.vim25.mo.ComputeResource;
import com.vmware.vim25.mo.Datacenter;
import com.vmware.vim25.mo.Datastore;
import com.vmware.vim25.mo.DistributedVirtualPortgroup;
import com.vmware.vim25.mo.HostSystem;
import com.vmware.vim25.mo.ManagedEntity;
import com.vmware.vim25.mo.Network;
import com.vmware.vim25.mo.VirtualMachine;
import com.vmware.vim25.mo.VmwareDistributedVirtualSwitch;

/**
 * 组装对象工具类
 * 
 * @author weiwei
 *
 */
public class AssembleTools {

	public static AssembleTools getInstance() {
		return new AssembleTools();
	}

	/**
	 * 组装数据中心相关元数据
	 * 
	 * @param vdcs
	 * @param entity
	 * @throws Exception
	 */
	public VDCModel assembleDc(ManagedEntity entity) throws Exception {
		Datacenter datacenter = (Datacenter) entity;
		List<NetworkModel> networks = Lists.newArrayList();
		ManagedEntity[] managedEntities = datacenter.getNetworkFolder().getChildEntity();
		for (ManagedEntity network : managedEntities) {
			if (network instanceof Network && !(network instanceof DistributedVirtualPortgroup)) {
				int portNum = -1;
				HostSystem[] hosts = ((Network) network).getHosts();
				if (hosts.length > 0) {
					HostSystem host = ((Network) network).getHosts()[0];
					HostPortGroupConfig[] portGroupConfigs = host.getHostNetworkSystem().getNetworkConfig()
							.getPortgroup();
					HostVirtualSwitchConfig[] vSwitchConfigs = host.getHostNetworkSystem().getNetworkConfig()
							.getVswitch();
					for (HostPortGroupConfig portGroupConfig : portGroupConfigs) {
						if (network.getName().equals(portGroupConfig.getSpec().getName())) {
							for (HostVirtualSwitchConfig vSwitchConfig : vSwitchConfigs) {
								if (portGroupConfig.getSpec().getVswitchName().equals(vSwitchConfig.getName())) {
									portNum = vSwitchConfig.getSpec().getNumPorts();
									break;
								}
							}
						}
					}
				}
				if (portNum != -1 && portNum >= 8) {
					NetworkModel networkModel = new NetworkModel(network.getName(), "", "VSWITCH",
							network.getOverallStatus().toString(), null, null, new ArrayList<>(), "",
							network.getMOR().getVal(), portNum - 8);
					networks.add(networkModel);
				} else {
					NetworkModel networkModel = new NetworkModel(network.getName(), "", "VSWITCH",
							network.getOverallStatus().toString(), null, null, new ArrayList<>(), "",
							network.getMOR().getVal(), null);
					networks.add(networkModel);
				}
			} else if (network instanceof VmwareDistributedVirtualSwitch) {
				List<PortGroupModel> models = Lists.newArrayList();
				Map<String, String> portMap = Maps.newHashMap();
				ManagedObjectReference[] references = ((VmwareDistributedVirtualSwitch) network).getConfig()
						.getUplinkPortgroup();
				if (null != references) {
					for (ManagedObjectReference reference : references) {
						DistributedVirtualPortgroup uplinkPort = new DistributedVirtualPortgroup(
								entity.getServerConnection(), reference);
						PortGroupModel model = new PortGroupModel(uplinkPort.getName(), "UPLINK",
								uplinkPort.getConfig().getNumPorts(), uplinkPort.getMOR().getVal(),
								uplinkPort.getConfig().getDescription());
						portMap.put(uplinkPort.getMOR().getVal(), uplinkPort.getName());
						models.add(model);
					}
				}
				DistributedVirtualPortgroup[] portgroups = ((VmwareDistributedVirtualSwitch) network).getPortgroup();
				for (DistributedVirtualPortgroup portgroup : portgroups) {
					if (portMap.containsKey(portgroup.getMOR().getVal())) {
						continue;
					}
					PortGroupModel model = new PortGroupModel(portgroup.getName(), "DVPORT",
							portgroup.getConfig().getNumPorts(), portgroup.getMOR().getVal(),
							portgroup.getConfig().getDescription());
					models.add(model);
				}
				NetworkModel networkModel = new NetworkModel(network.getName(), "", "DVSWITCH",
						network.getOverallStatus().toString(), null, null, new ArrayList<>(), "",
						network.getMOR().getVal(),
						((VmwareDistributedVirtualSwitch) network).getConfig().getNumPorts());
				networkModel.setGroups(models);
				networks.add(networkModel);
			}
		}

		VDCModel vdc = new VDCModel(datacenter.getName(), 0l, 0l, 0l, 0l, 0l, 0l, null, null, null,
				datacenter.getMOR().getVal());
		List<ClusterModel> clusters = Lists.newArrayList();
		List<HostModel> hosts = Lists.newArrayList();
		List<DataStoreModel> stores = Lists.newArrayList();
		ManagedEntity[] hostEntities = datacenter.getHostFolder().getChildEntity();
		Datastore[] datastores = datacenter.getDatastores();
		if (null != datastores) {
			for (Datastore datastore : datastores) {
				DatastoreSummary datastoreSummary = datastore.getSummary();
				Long diskCapacity = datastoreSummary.getCapacity();
				Long freeCapacity = datastoreSummary.getFreeSpace();
				BigDecimal capacity = new BigDecimal(diskCapacity);
				BigDecimal freedisk = new BigDecimal(freeCapacity);
				diskCapacity = capacity.divide(new BigDecimal(1024 * 1024 * 1024), 1, RoundingMode.HALF_UP).longValue();
				freeCapacity = freedisk.divide(new BigDecimal(1024 * 1024 * 1024), 1, RoundingMode.HALF_UP).longValue();
				// 获取存储下的虚拟机与模板
				int templateNum = 0;// 模板数量
				int vmNum = 0;// 虚拟机数量
				VirtualMachine[] vms = datastore.getVms();
				if (null != vms) {
					for (VirtualMachine vm : vms) {
						if (null != vm.getConfig()) {
							if (vm.getConfig().isTemplate()) {
								templateNum++;
							} else {
								vmNum++;
							}
						}
					}
				}
				int hostNum = 0;
				if (null != datastore.getHost()) {
					hostNum = datastore.getHost().length;
				}
				DataStoreModel dataStoreModel = new DataStoreModel(datastoreSummary.getName(),
						datastoreSummary.getType(), datastoreSummary.getUrl(), diskCapacity, freeCapacity, hostNum,
						vmNum, templateNum, datastoreSummary.getDatastore().getVal());
				dataStoreModel.setStatus(datastore.getOverallStatus().toString());
				stores.add(dataStoreModel);
			}
		}
		if (null != hostEntities) {
			for (ManagedEntity hostEntity : hostEntities) {
				if (hostEntity instanceof ClusterComputeResource) {
					ClusterComputeResource cluster = (ClusterComputeResource) hostEntity;
					clusters.add(assembleCluster(cluster));
				} else if (hostEntity instanceof ComputeResource) {
					ComputeResource hostSystem = (ComputeResource) hostEntity;
					HostModel model = assembleVmwareHost(hostSystem.getHosts()[0]);
					if (null != model) {
						hosts.add(model);
					}
				}
			}
		}
		Long cpuTotal = 0l;
		Long memTotal = 0l;
		Long diskTotal = 0l;
		Long cpuUsed = 0l;
		Long memUsed = 0l;
		Long diskUsed = 0l;
		for (ClusterModel clusterModel : clusters) {
			cpuTotal += clusterModel.getCpuTotal();
			memTotal += clusterModel.getMemTotal();
			diskTotal += clusterModel.getDiskTotal();
			cpuUsed += clusterModel.getCpuUsed();
			memUsed += clusterModel.getMemUsed();
			diskUsed += clusterModel.getDiskUsed();
		}
		for (HostModel hostModel : hosts) {
			cpuTotal += hostModel.getCpuTotal();
			memTotal += hostModel.getMemTotal();
			diskTotal += hostModel.getDiskTotal();
			cpuUsed += hostModel.getCpuUsed();
			memUsed += hostModel.getMemUsed();
			diskUsed += hostModel.getDiskUsed();
		}
		vdc.setCpuTotal(cpuTotal);
		vdc.setDiskTotal(diskTotal);
		vdc.setMemTotal(memTotal);
		vdc.setCpuUsed(cpuUsed);
		vdc.setMemUsed(memUsed);
		vdc.setDiskUsed(diskUsed);
		vdc.setClusters(clusters);
		vdc.setHosts(hosts);
		vdc.setStores(stores);
		vdc.setNetworks(networks);
		return vdc;
	}

	/**
	 * 组装主机集群相关元数据
	 * 
	 * @param clusters
	 * @param entity
	 * @throws Exception
	 */
	public ClusterModel assembleCluster(ClusterComputeResource entity) throws Exception {
		ClusterModel cluster = new ClusterModel();
		cluster.setName(entity.getName());
		cluster.setClusterVal(entity.getMOR().getVal());
		HostSystem[] hostSystems = entity.getHosts();
		List<HostModel> hosts = Lists.newArrayList();
		int templateNum = 0;// 模板数量
		int vmNum = 0;// 虚拟机数量
		// 遍历集群中hostSystem，判断所有的hostSystem下一共有多少虚拟机，即该集群下一共有多少虚拟机
		if (null != hostSystems) {
			for (HostSystem hostSystem : hostSystems) {
				VirtualMachine[] vmArray = hostSystem.getVms();// 某一个hostSystem下所有的虚拟机（取出的数量=虚拟机+模板）
				for (VirtualMachine virtualMachine : vmArray) {
					if (null == virtualMachine.getConfig()) {
						continue;
					}
					if (virtualMachine.getConfig().isTemplate()) {
						templateNum++;
					} else {
						vmNum++;
					}
				}
				HostModel model = assembleVmwareHost(hostSystem);
				if (null != model) {
					hosts.add(model);
				}
			}
		}

		cluster.setHosts(hosts);
		cluster.setTemplateNum(templateNum);
		cluster.setVmNum(vmNum);
		// 集群中宿主机（物理机）数量
		if (null != hostSystems) {
			cluster.setHostNum(hostSystems.length);
		} else {
			cluster.setHostNum(0);
		}

		Long cpuTotal = 0l;
		Long memTotal = 0l;
		Long diskTotal = 0l;
		Long cpuUsed = 0l;
		Long memUsed = 0l;
		Long diskUsed = 0l;
		int cpuCore = 0;
		for (HostModel hostModel : hosts) {
			cpuTotal += hostModel.getCpuTotal();
			memTotal += hostModel.getMemTotal();
			diskTotal += hostModel.getDiskTotal();
			cpuUsed += hostModel.getCpuUsed();
			memUsed += hostModel.getMemUsed();
			diskUsed += hostModel.getDiskUsed();
			cpuCore += hostModel.getCpuCore();
		}
		cluster.setCpuTotal(cpuTotal);
		cluster.setMemTotal(memTotal);
		cluster.setDiskTotal(diskTotal);
		cluster.setCpuUsed(cpuUsed);
		cluster.setMemUsed(memUsed);
		cluster.setDiskUsed(diskUsed);
		cluster.setCpuCore(cpuCore);
		return cluster;
	}

	public HostModel assembleVmwareHost(HostSystem host) throws Exception {
		HostModel hostModel = new HostModel();
		List<ServerModel> serverModels = Lists.newArrayList();
		HostListSummary summary = host.getSummary();
		if (null == summary || null == summary.getHardware()) {
			return null;
		}
		hostModel.setName(host.getName());
		hostModel.setUuid(summary.getHardware().getUuid());
		hostModel.setVendor(summary.getHardware().getVendor());
		hostModel.setCatalog(host.getConfig().getProduct().getName());
		hostModel.setCategory(summary.getHardware().getModel());
		hostModel.setCpuModel(summary.getHardware().getCpuModel());
		hostModel.setCpuNum((int) summary.getHardware().getNumCpuPkgs());
		hostModel.setCpuCore((int) summary.getHardware().getNumCpuCores());
		hostModel.setCpuTotal(Long.valueOf(summary.getHardware().getCpuMhz()) * summary.getHardware().getNumCpuCores());
		hostModel.setMaintain(host.getSummary().getRuntime().isInMaintenanceMode());// 物理机是否处于维护模式
		HostSystemConnectionState connState = host.getSummary().getRuntime().getConnectionState();// 物理机连接状态
		if (connState.equals(HostSystemConnectionState.connected)) {
			hostModel.setConnected(true);
			hostModel.setCpuUsed(summary.getQuickStats().getOverallCpuUsage().longValue());
			hostModel.setMemUsed(summary.getQuickStats().getOverallMemoryUsage().longValue());
		} else {
			hostModel.setConnected(false);
			hostModel.setCpuUsed(0L);
			hostModel.setMemUsed(0L);
		}
		// 获取宿主机（物理机的IP）
		HostVirtualNic[] virtualNicArray = host.getHostNetworkSystem().getNetworkInfo().getVnic();// 获取虚拟网卡
		if (null != virtualNicArray) {
			for (HostVirtualNic hostVirtualNic : virtualNicArray) {
				String hostIp = hostVirtualNic.getSpec().getIp().getIpAddress();// 获取物理机的ip
				if (!StringUtils.isEmpty(hostIp)) {
					hostModel.setHostIp(hostIp);
					break;
				}
			}
		}
		BigDecimal memory = new BigDecimal(host.getHardware().getMemorySize());
		hostModel.setMemTotal(memory.divide(new BigDecimal(1024 * 1024), 1, RoundingMode.HALF_UP).longValue());
		List<String> stores = Lists.newArrayList();
		Datastore[] datastores = host.getDatastores();
		Long diskCapacity = 0l;
		Long freeCapacity = 0l;
		if (null != datastores) {
			List<DataStoreModel> models = Lists.newArrayList();
			for (Datastore datastore : datastores) {
				DatastoreSummary datastoreSummary = datastore.getSummary();
				stores.add(datastoreSummary.getDatastore().getVal());
				diskCapacity += datastoreSummary.getCapacity();
				freeCapacity += datastoreSummary.getFreeSpace();

				Long disk = datastoreSummary.getCapacity();
				Long free = datastoreSummary.getFreeSpace();
				BigDecimal capacity = new BigDecimal(disk);
				BigDecimal freedisk = new BigDecimal(free);
				disk = capacity.divide(new BigDecimal(1024 * 1024 * 1024), 1, RoundingMode.HALF_UP).longValue();
				free = freedisk.divide(new BigDecimal(1024 * 1024 * 1024), 1, RoundingMode.HALF_UP).longValue();
				// 获取存储下的虚拟机与模板
				int templateNum = 0;// 模板数量
				int vmNum = 0;// 虚拟机数量
				VirtualMachine[] vms = datastore.getVms();
				if (null != vms) {
					for (VirtualMachine vm : vms) {
						if (null != vm.getConfig()) {
							if (vm.getConfig().isTemplate()) {
								templateNum++;
							} else {
								vmNum++;
							}
						}
					}
				}
				int hostNum = 0;
				if (null != datastore.getHost()) {
					hostNum = datastore.getHost().length;
				}
				DataStoreModel dataStoreModel = new DataStoreModel(datastoreSummary.getName(),
						datastoreSummary.getType(), datastoreSummary.getUrl(), disk, free, hostNum, vmNum, templateNum,
						datastoreSummary.getDatastore().getVal());
				dataStoreModel.setStatus(datastore.getOverallStatus().toString());
				models.add(dataStoreModel);
			}
			hostModel.setDataStores(models);
			hostModel.setDatastoreNum(datastores.length);
		} else {
			hostModel.setDatastoreNum(0);
		}
		BigDecimal capacity = new BigDecimal(diskCapacity);
		BigDecimal freedisk = new BigDecimal(freeCapacity);
		diskCapacity = capacity.divide(new BigDecimal(1024 * 1024 * 1024), 1, RoundingMode.HALF_UP).longValue();
		freeCapacity = freedisk.divide(new BigDecimal(1024 * 1024 * 1024), 1, RoundingMode.HALF_UP).longValue();
		hostModel.setStores(stores);
		hostModel.setDiskTotal(diskCapacity);
		hostModel.setDiskUsed(diskCapacity - freeCapacity);

		// 获取网络
		List<String> nets = Lists.newArrayList();
		Network[] networks = host.getNetworks();
		for (Network network : networks) {
			nets.add(network.getMOR().getVal());
		}
		hostModel.setNetworks(nets);
		// 获取宿主机下的所有虚拟机
		VirtualMachine[] machines = host.getVms();// 某一个hostSystem下所有的虚拟机（取出的数量=虚拟机+模板）

		int templateNum = 0;// 物理机下模板数量
		int vmNum = 0;// 物理机下虚拟机下数量
		if (null != machines) {
			for (VirtualMachine machine : machines) {
				ServerModel serverModel = convertServer(machine);
				if (null != serverModel) {
					if (serverModel.getIsTemplate()) {
						templateNum++;
					} else {
						vmNum++;
					}
					serverModels.add(serverModel);
				}
			}
		}

		// 获取宿主机的电源状态
		HostSystemPowerState hostSystemPowerState = host.getRuntime().getPowerState();
		String hostPowerState = "STOPPED";
		if (hostSystemPowerState.equals(HostSystemPowerState.poweredOn)) {
			hostPowerState = "RUNNING";
		} else if (hostSystemPowerState.equals(HostSystemPowerState.poweredOff)) {
			hostPowerState = "STOPPED";
			hostModel.setConnected(false);
		} else if (hostSystemPowerState.equals(HostSystemPowerState.unknown)) {
			if (host.getRuntime().getConnectionState().equals(HostSystemConnectionState.notResponding)) {
				hostPowerState = "STOPPED";
			} else {
				hostPowerState = "UNKNOWN";
			}
			hostModel.setConnected(false);
		}

		// 获取特定物理机下已被使用的物理网卡（同一物理机下网卡的名称不重复
		List<String> adapterList = Lists.newArrayList();
		this.getAdapter(host, adapterList);
		// 获取机器下的所有的所有的物理网卡
		List<NetworkCardModel> networkModels = Lists.newArrayList();
		PhysicalNic[] pNics = host.getConfig().getNetwork().getPnic();
		if (null != pNics) {
			for (PhysicalNic physicalNic : pNics) {
				NetworkCardModel networkCardModel = new NetworkCardModel();
				if (adapterList.contains(physicalNic.getDevice())) {
					networkCardModel.setUsed(true);
				} else {
					networkCardModel.setUsed(false);
				}
				networkCardModel.setName(physicalNic.getDevice());
				networkCardModel.setMac(physicalNic.getMac());
				networkModels.add(networkCardModel);
			}
		}
		hostModel.setNetcards(networkModels);
		hostModel.setVmNum(vmNum);// 宿主机（物理机）包含的虚拟机数量
		hostModel.setPowerState(hostPowerState);// 宿主机电源状态
		hostModel.setTemplateNum(templateNum);
		hostModel.setServers(serverModels);
		hostModel.setStatus(hostPowerState);
		return hostModel;
	}

	/**
	 * 获取物理机上已被使用的物理网卡
	 * 
	 * @param hostSystem
	 * @param adapterList
	 * @throws Exception
	 */
	private void getAdapter(HostSystem hostSystem, List<String> adapterList) throws Exception {
		HostVirtualSwitchConfig[] vsConfigs = hostSystem.getHostNetworkSystem().getNetworkConfig().getVswitch();
		if (null != vsConfigs) {
			for (HostVirtualSwitchConfig vsConfig : vsConfigs) {
				HostVirtualSwitchBondBridge bridge = (HostVirtualSwitchBondBridge) vsConfig.getSpec().getBridge();
				if (null != bridge) {
					String[] nics = bridge.getNicDevice();
					for (String nic : nics) {
						adapterList.add(nic);
					}
				}
			}
		}
		// 分布式交换机上被用的物理网卡
		HostProxySwitch[] hostProxySwitchs = hostSystem.getHostNetworkSystem().getNetworkInfo().getProxySwitch();
		if (null != hostProxySwitchs) {
			for (HostProxySwitch hostProxySwitch : hostProxySwitchs) {
				DistributedVirtualSwitchHostMemberPnicBacking dvsHostPnicBacking = (DistributedVirtualSwitchHostMemberPnicBacking) hostProxySwitch
						.getSpec().getBacking();
				DistributedVirtualSwitchHostMemberPnicSpec[] dvsHostPnics = dvsHostPnicBacking.getPnicSpec();
				if (null != dvsHostPnics) {
					for (DistributedVirtualSwitchHostMemberPnicSpec dvsHostPnic : dvsHostPnics) {
						adapterList.add(dvsHostPnic.getPnicDevice());
					}
				}
			}
		}
	}

	/**
	 * 转换字段
	 * 
	 * @param entity
	 * @return
	 * @throws RemoteException
	 * @throws RuntimeFault
	 * @throws InvalidProperty
	 */
	public ServerModel convertServer(VirtualMachine machine) throws Exception {
		if (null == machine) {
			return null;
		}
		// 虚拟机配置信息
		VirtualMachineConfigInfo config = machine.getConfig();
		ServerModel serverModel = new ServerModel();
		if (null != machine.getSnapshot()) {
			VirtualMachineSnapshotTree[] snapshotArray = machine.getSnapshot().getRootSnapshotList();
			List<SnapshotModel> snapshotList = Lists.newArrayList();
			// 获取虚拟机下的所有快照
			// 遍历取得的快照tree获取所有的快照
			snapshotList = traverseSnapshotTree(snapshotArray, snapshotList);
			serverModel.setSnapshots(snapshotList);
		}
		VirtualMachineSummary summary = machine.getSummary();
		serverModel.setCpu(summary.getConfig().getNumCpu());
		serverModel.setInstanceId(summary.getConfig().getInstanceUuid());
		serverModel.setIsTemplate(summary.getConfig().isTemplate());
		serverModel.setManagerIp(summary.getGuest().getIpAddress());
		serverModel.setMemory(summary.getConfig().getMemorySizeMB());
		serverModel.setName(machine.getName());
		serverModel.setStatus(summary.getRuntime().getPowerState().name());
		serverModel.setUuid(summary.getConfig().getUuid());
		serverModel.setRemark(summary.getConfig().getAnnotation());
		if (null == summary.getGuest().getToolsStatus()) {
			serverModel.setToolsInstalled(false);
			serverModel.setToolsRunning(false);
		} else if ("toolsOk".equalsIgnoreCase(summary.getGuest().getToolsStatus().toString())) {
			serverModel.setToolsInstalled(true);
			serverModel.setToolsRunning(true);
		} else if ("toolsNotInstalled".equalsIgnoreCase(summary.getGuest().getToolsStatus().toString())) {
			serverModel.setToolsInstalled(false);
			serverModel.setToolsRunning(false);
		} else {
			serverModel.setToolsInstalled(true);
			serverModel.setToolsRunning(false);
		}
		Datastore[] datastores = machine.getDatastores();
		if (null != datastores && datastores.length > 0) {
			List<String> storeList = Lists.newArrayList();
			String stores = null;
			for (int i = 0; i < datastores.length; i++) {
				if (i == 0) {
					stores = datastores[i].getName();
				} else {
					stores += "," + datastores[i].getName();
				}
				storeList.add(datastores[i].getSummary().getDatastore().getVal());
			}
			serverModel.setStores(storeList);
			serverModel.setDatastores(stores);
		}
		Network[] networks = machine.getNetworks();
		if (null != networks && networks.length > 0) {
			List<String> nets = Lists.newArrayList();
			for (Network network : networks) {
				nets.add(network.getMOR().getVal());
			}
			serverModel.setNetworks(nets);
		}
		if (null != config) {
			// 虚拟机系统磁盘
			long diskSize = 0;
			// 获取虚拟机下所有的物理网卡
			List<NetworkCardModel> networkModels = Lists.newArrayList();
			// 虚拟机关联设备
			VirtualDevice[] devices = config.getHardware().getDevice();
			for (int i = 0; devices != null && i < devices.length; i++) {
				VirtualDevice device = devices[i];
				if (device instanceof VirtualDisk) {
					diskSize += ((VirtualDisk) device).getCapacityInKB();
				}
				if (device instanceof VirtualEthernetCard) {
					NetworkCardModel networkCardModel = new NetworkCardModel();
					networkCardModel.setLabel(device.getDeviceInfo().getLabel());
					networkCardModel.setMac(((VirtualEthernetCard) device).getMacAddress());
					networkCardModel.setUsed(true);
					String name = null;
					try {
						name = ((VirtualDeviceDeviceBackingInfo) device.getBacking()).getDeviceName();
					} catch (Exception e) {
						name = ((VirtualEthernetCardDistributedVirtualPortBackingInfo) (device.getBacking())).getPort()
								.getPortgroupKey();
					}
					networkCardModel.setName(name);
					networkModels.add(networkCardModel);
				}
			}
			int disk = new BigDecimal(diskSize).divide(new BigDecimal(1024 * 1024)).intValue();
			serverModel.setDisk(disk);
			serverModel.setNetcards(networkModels);
		} else {
			serverModel.setCpu(0);
			serverModel.setMemory(0);
			serverModel.setDisk(0);
			serverModel.setStatus("exception");
		}
		return serverModel;
	}

	/**
	 * 遍历从虚拟机获取的快照tree
	 * 
	 * @param snapshotTreeArray
	 * @return
	 */
	public List<SnapshotModel> traverseSnapshotTree(VirtualMachineSnapshotTree[] trees,
			List<SnapshotModel> snapshotList) {
		if (null != trees) {
			for (VirtualMachineSnapshotTree tree : trees) {
				snapshotList.add(convert(tree));
				if (null != tree.getChildSnapshotList()) {
					traverseSnapshotTree(tree.getChildSnapshotList(), snapshotList);
				}
			}
		}
		return snapshotList;
	}

	/**
	 * 把虚拟机获取的快照转换成自身想要的对象
	 * 
	 * @param virtualMachineSnapshotTree
	 * @return
	 */
	private SnapshotModel convert(VirtualMachineSnapshotTree tree) {
		SnapshotModel model = new SnapshotModel();
		if (null != tree) {
			// 快照创建时间
			model.setCreateTime(tree.getCreateTime().getTime());
			// 快照名称
			model.setName(tree.getName());
			// 快照ID
			model.setSnapshotId(tree.getId().toString());
			model.setSnapshotVal(tree.getSnapshot().getVal());
			// 快照状态
			if (tree.getState().equals(tree.state)) {
				model.setStatus("AVAILABLE");
			} else {
				model.setStatus("UNAVAILABLE");
			}
			model.setRemark(tree.getDescription());
		}
		return model;
	}

}
